package tableaux;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;

import entities.Individual;
import entities.assertion.Assertion;
import entities.assertion.ConceptAssertion;
import entities.assertion.RoleAssertion;
import entities.concept.Concept;
import entities.role.Role;
import kb.*;

/**
 * A data graph is built upon the initial ABox, and is associated with that
 * ABox. For TBox subsumption check only, this should be empty. Nodes are
 * individuals and literals, while edges are roles.
 * 
 * @author j55wu
 * 
 */
public class InitGraph {
	private ABox ab;
	private Completion dcomp;

	public InitGraph(Completion dc, ABox ab) {
		this.dcomp = dc;
		this.ab = ab;
	}

	public ABox getAssociatedABox() {
		return this.ab;
	}

	public Completion getAssociatedCompletion() {
		return this.dcomp;
	}

	// no edges, only isolated nodes
	public boolean simpleDataGraph() {
		return this.ab.isRoleAssertionFreeABox();
	}

	public void ABox2DataGraph() {
		Map<Individual, HashMap<Role, HashSet<Individual>>> roleAssertions = this.ab
				.getRoleAssertions();
		HashMap<Individual, Concept> conceptAssertions = this.ab
				.getConceptAssertions();
		for (Individual ind : this.ab.getABoxIndividuals()) {
			if (roleAssertions.keySet().contains(ind)) {
				HashMap<Role, HashSet<Individual>> rolefiller = roleAssertions
						.get(ind);
				for (Entry<Role, HashSet<Individual>> e : rolefiller.entrySet()) {
					Role r = e.getKey();
					Role ir = dcomp.getInitTBox().getRoleBox().getInverseRole(r);
					ind.addChild(r, e.getValue());
					ind.addParents(ir, e.getValue());
					for (Individual n : e.getValue()) {
						n.addParents(r, ind);
						n.addChild(ir, ind);
					}
				}
			}
			if (conceptAssertions.keySet().contains(ind)) {
				ind.addLabels(conceptAssertions.get(ind));
			}
		}
		return;
	}

	public void addNewAssertion(Assertion as) {
		if (as instanceof ConceptAssertion) {
			ConceptAssertion ca = (ConceptAssertion) as;
			Individual ind = ca.getIndividual();
			Concept c = ca.getConcept();
			ind.addLabels(c);
			this.ab.insertConceptAssertions(ca);
		} else {
			RoleAssertion ra = as.asRoleAssertion();
			Individual a = ra.getFirstIndividual(), b = ra
					.getSecondIndividual();
			Role r = ra.getRole();
			a.addChild(r, b);
			this.ab.insertAssertions(ra);
		}
	}

}
